#include <iostream>
#include "httplib.h"
#include "add_contact.pb.h"
#include "ContactsException.h"

using std::cin;
using std::cout;
using std::cerr;
using std::endl;

using namespace httplib;

// int main()
// {
//   cout << "----------服务启动----------" << endl;
//   Server server;
//   server.Post("/test-post", [](const Request& req, Response& res)
//   {
//     cout << "收到post 请求" << endl;
//     res.status = 200;
//   });

//   server.Get("/test-get", [](const Request& req, Response& res)
//   {
//     cout << "收到get请求" << endl;
//     res.status = 200;
//   });

//   server.listen("0.0.0.0",8080);
//   return 0;
// }

void printContact(add_contact::AddContactRequest& req)
{
      std::cout << "----------联系人" << std::endl;
      std::cout << "联系人姓名 : " << req.name() << std::endl;
      std::cout << "联系人年龄 : " << req.age() << std::endl;

      for (int i = 0; i < req.phone_size(); ++i)
      {
        const add_contact::AddContactRequest_Phone &phone =req.phone(i);
        std::cout << "联系人电话" << i + 1 << ": " << phone.number();

        //打印联系人电话
        std::cout << " ( " << phone.PhoneType_Name(phone.type()) << ")" << std::endl;
      }  
}

static unsigned int random_char() {
    // ⽤于随机数引擎获得随机种⼦
    std::random_device rd; 
    // mt19937是c++11新特性，它是⼀种随机数算法，⽤法与rand()函数类似，但是mt19937具有速度快，周期⻓的特点
    // 作⽤是⽣成伪随机数
    std::mt19937 gen(rd()); 
    // 随机⽣成⼀个整数i 范围[0, 255]
    std::uniform_int_distribution<> dis(0, 255);
    return dis(gen);
 }

 // ⽣成 UUID （通⽤唯⼀标识符）
 static std::string generate_hex(const unsigned int len) {
    std::stringstream ss;
    // ⽣成 len 个16进制随机数，将其拼接⽽成
    for (auto i = 0; i < len; i++) {
        const auto rc = random_char();
        std::stringstream hexstream;
        hexstream << std::hex << rc;
        auto hex = hexstream.str();
        ss << (hex.length() < 2 ? '0' + hex : hex);
    }
    return ss.str();
 }

int main()
{
  cout << "----------服务启动----------" << endl;
  Server server;
  server.Post("/contacts/add", [](const Request& req, Response &res)
  {
    cout << "接到post请求" << endl;
    
    //反序列化
    add_contact::AddContactRequest  request;
    add_contact::AddContactResponse response;
    try
    {
      if (!request.ParseFromString(req.body))
      {
        throw ContactsException("AddContactRequest反序列化失败");
      }

      //新增联系人,持久化存储通讯录--》打印新增联系人信息
      printContact(request);


      //构造 response:res.body
      response.set_sucess(true);
      response.set_uid(generate_hex(10));

      //res.body(序列化response)
      std::string response_str;
      if (!response.SerializeToString(&response_str))
      {
        throw ContactsException("AddContactResponse序列化失败!");
      }
      res.status = 200;
      res.body   = response_str;
      res.set_header("Content-Type", "application/protobuf");
    }
    catch(ContactsException& e)
    {
      res.status = 500;
      response.set_sucess(false);
      response.set_error_desc(e.what());
      std::string response_str;
      if (response.SerializeToString(&response_str))
      {
        res.body = response_str;
        res.set_header("Content-Type", "application/protobuf");
      }
      cout << "/contacts/add 发生异常,异常信息:" << e.what() << endl;
    }
  });

  server.listen("0.0.0.0",8080);
  return 0;
}